package com.example.demo.service.impl;

import com.example.demo.client.evt.cssmqry.GetRegionChildrenEvt;
import com.example.demo.client.evt.cssmqry.role.QryRoleEvt;
import com.example.demo.client.vm.cssmqry.region.RegionVm;
import com.example.demo.client.vm.cssmqry.user.UserVm;
import com.example.demo.client.vm.sysbasequery.QueryUserVm;
import com.example.demo.client.vm.sysbasequery.RoleTreeVm;
import com.example.demo.domain.CsSmImportLogD;
import com.example.demo.domain.Role;
import com.example.demo.enums.ResourceObjectTypeEnum;
import com.example.demo.format.TreeBuilder;
import com.example.demo.mapper.CsSmImportLogDMapper;
import com.example.demo.mapper.MenuMapper;
import com.example.demo.mapper.RoleMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.repository.RoleRepository;
import com.example.demo.security.SecurityUtils;
import com.example.demo.service.BaseService;
import com.example.demo.service.RoleService;
import com.example.demo.web.rest.constant.DatabaseConstant;
import com.example.demo.web.rest.evt.*;
import com.example.demo.web.rest.vm.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Description:
 *
 * @Author zmf
 * @Date 2018/12/14  10:15
 */
@Service
@Transactional
public class RoleServiceImpl extends BaseService implements RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    CsSmImportLogDMapper csSmImportLogDMapper;

    @Override
    public void delRole(Long roleId) {
        roleMapper.delRolePermission(roleId, null);
        roleRepository.deleteById(roleId);
    }

    @Override
    public void delUserRole(UserRoleEvt evt) {
        roleMapper.delUserRole(evt);
    }

    @Override
    public Long saveRole(SaveRoleEvt evt) throws ParseException {
        Role role = new Role();
        BeanUtils.copyProperties(evt.getRoleEvt(), role);
        /*Long currentUserId = getCurrentUserId();
        role.setCreateUserId(currentUserId);
        role.setUpdateUserId(currentUserId);
        role.setEnabled(1);*/
        String username = SecurityUtils.getCurrentUserLogin().get();
        Date now = nowDateTime();
        role.setUpdateUserName(username);
        role.setUpdateTime(now);
        Long roleId;
        String parentFullRoleId = "";
        if (role.getParentRoleId() != null) {
            IdEvt idEvt = new IdEvt();
            idEvt.setId(role.getParentRoleId());
            String tempFullRoleId = baseQueryClient.getFullRoleId(idEvt).getBody();
            if (StringUtils.isNotBlank(tempFullRoleId)) {
                parentFullRoleId = tempFullRoleId;
            }
        }
        if (role.getRoleId() == null) {
            //新增角色 默认插入时间和更新时间一致
            role.setCreateUserName(username);
            role.setInsertTime(now);
            TableIdSizeEvt tableIdSizeEvt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_ROLE, DatabaseConstant.ID_SIZE);
            roleId = baseQueryClient.getTableId(tableIdSizeEvt);
            role.setRoleId(roleId);

            //新增自动填上角色区域信息
            UserVm userVm = userMapper.getUser(username);
            if (userVm != null) {
                //获取当前登录用户的区域ID
                role.setRegionId(userVm.getRegionId());
                role.setFullRegionId(userVm.getFullRegion());
            }
            roleMapper.insertRole(role);
        } else {
            role.setUpdateTime(now);
            roleMapper.updateRole(role);
        }

//        roleRepository.save(role);
        roleId = role.getRoleId();
        if (StringUtils.isBlank(parentFullRoleId)) {
            roleRepository.updateFullRoleId("," + roleId + ",", roleId);
        } else {
            roleRepository.updateFullRoleId(parentFullRoleId + roleId + ",", roleId);
        }
        //删除角色与权限关联表
        if (evt.getDelPermissionId() != null && evt.getDelPermissionId().size() > 0) {
            roleMapper.delRolePermission(roleId, evt.getDelPermissionId());
        }
        // 插入角色与权限关联表
        if (evt.getAddPermissionId() != null && evt.getAddPermissionId().size() > 0) {
            roleMapper.addRolePermission(roleId, evt.getAddPermissionId());
        }

        ResourceRelationEvt resourceRelationEvt = new ResourceRelationEvt();
        resourceRelationEvt.setId(roleId);
        resourceRelationEvt.setType(ResourceObjectTypeEnum.ROLE_REF.getValue());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = format.format(new Date());
        resourceRelationEvt.setCreateTime(nowTime);
        resourceRelationEvt.setUpdateTime(nowTime);
        resourceRelationEvt.setCreateUserName(username);
        resourceRelationEvt.setUpdateUserName(username);
        // 删除用户组与资源关系
        if (evt.getDelResource() != null && evt.getDelResource().size() > 0) {
            List<ResourceEvt> delResource = evt.getDelResource();
            resourceRelationEvt.setList(delResource);
            roleMapper.delRoleResource(resourceRelationEvt);
        }
        // 添加角色与资源关系
        if (evt.getAddResource() != null && evt.getAddResource().size() > 0) {
            List<ResourceEvt> addResource = evt.getAddResource();
            resourceRelationEvt.setList(addResource);
            roleMapper.addRoleResource(resourceRelationEvt);
        }
        return roleId;
    }

    @Override
    public void addUserRole(RelationEvt evt) {
        //保存新的关联用户
        roleMapper.addUserRole(evt);
    }

    @Override
    public List<RoleTreeVm> getRoleTreeInfos(QryRoleEvt evt) {
        List<RoleTreeVm> list = new ArrayList<>();
        if (StringUtils.isEmpty(evt.getRoleName()) && StringUtils.isEmpty(evt.getKeyword())) {
            list = roleMapper.getRoleInfos();
        } else {
            List<String> fullRoleIds = roleMapper.getFullRoleIds(evt);
            if (fullRoleIds != null && fullRoleIds.size() > 0) {
                String fullRoleIdAppend = StringUtils.join(fullRoleIds, ",");
                String fullRoleId = fullRoleIdAppend.replaceAll(",,,", ",");
                Set<String> fullIdSet = new HashSet<>(Arrays.asList(fullRoleId.split(",")));
                list = roleMapper.getRoleByIds(fullIdSet);
            }
        }

        GetRegionChildrenEvt qryEvt = new GetRegionChildrenEvt();
        List<RegionVm> regionList = baseQueryClient.getRegionList(qryEvt);
        for (RoleTreeVm roleTreeVm : list) {
            //查询对应角色的关联区域信息
            for (RegionVm region : regionList) {
                if (region.getRegionId().equals(roleTreeVm.getRegionId())) {
                    region.setChildren(null);
                    roleTreeVm.setRegionVm(region);
                }
            }
        }

        return list;
    }

    @Override
    public List<ExportRoleVm> getRoleTreeInfosExport(QryRoleEvt evt) {
        List<ExportRoleVm> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(evt.getRoleName()) || StringUtils.isNotEmpty(evt.getKeyword())) {
            List<String> fullRoleIds = roleMapper.getFullRoleIds(evt);
            if (fullRoleIds != null && fullRoleIds.size() > 0) {
                String fullRoleIdAppend = StringUtils.join(fullRoleIds, ",");
                String fullRoleId = fullRoleIdAppend.replaceAll(",,,", ",");
                Set<String> fullIdSet = new HashSet<>(Arrays.asList(fullRoleId.split(",")));
                list = roleMapper.getExportRoleByIds(fullIdSet);
            }
        } else {
            list = roleMapper.getExportRoleByIds(null);
        }
        return list;
    }


    @Override
    public List<RoleTreeVm> getParentRoleTree(IdEvt evt) {
        List<RoleTreeVm> list = TreeBuilder.newTreeBuilder(RoleTreeVm.class, Long.class)
                .buildToTreeList(roleMapper.getParentRoleTree(evt));
        Long id = evt.getId();
        deleteSelf(list, id);
        return list;
    }

    public void deleteSelf(List<RoleTreeVm> list, Long id) {
        if (list == null || list.size() == 0) {
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            RoleTreeVm vm = list.get(i);
            if (vm.getRoleId().equals(id)) {
                list.remove(i);
                return;
            }
            if (vm.getChildren() != null && vm.getChildren().size() > 0) {
                deleteSelf(vm.getChildren(), id);
            }
        }
    }

    @Override
    public String importRole(List<Map<String, Object>> paramsList, CsSmImportLogD csSmImportLogD) throws Exception {
        Map<String, Object> params;
        String allStr = "";
        RelationEvt relationEvt;
        List<String> relateIds;
        List<Long> roleIds = new ArrayList<>();
        List<Long> userIds = new ArrayList<>();
        List<String> tempStr = Lists.newArrayList();
        List<Map<String, Object>> insertDatas = Lists.newArrayList();
        for (int i = 0; i < paramsList.size(); i++) {
            params = paramsList.get(i);
            String[] roleName = String.valueOf(params.get("roleName")).split("/");
            List<ParentRoleVm> list = roleMapper.getRoleByName(roleName[roleName.length - 1]);
            if (list == null || list.size() == 0) {
                tempStr.add("第" + params.get("index") + "行角色不存在");
            } else {
                roleIds.add(list.get(0).getRoleId());
            }
            List<QueryUserVm> userList = userMapper.getUserByLoginName(String.valueOf(params.get("loginName")));
            if (userList == null || userList.size() == 0) {
                tempStr.add("第" + params.get("index") + "行用户不存在");
            } else {
                userIds.add(userList.get(0).getUserId());
            }
            if (CollectionUtils.isNotEmpty(tempStr)) {
                allStr += StringUtils.join(tempStr, ",");
                tempStr.clear();
                allStr += "\n";
            } else {
                insertDatas.add(params);
            }
        }
        if (!"".equals(allStr)) {
            csSmImportLogD.setStatus(0);
            csSmImportLogD.setRemark(allStr);
            csSmImportLogDMapper.updateById(csSmImportLogD);
            return allStr;
        }
        for (int i = 0; i < insertDatas.size(); i++) {
            if (roleMapper.checkExistUserRole(roleIds.get(i), userIds.get(i)) == 0) {
                relationEvt = new RelationEvt();
                relateIds = new ArrayList<>();
                relationEvt.setId(roleIds.get(i));
                relateIds.add(String.valueOf(userIds.get(i)));
                relationEvt.setRelateIds(relateIds);
                roleMapper.addUserRole(relationEvt);
            }
        }
        return allStr;
        /*List<ParentRoleVm> list = roleMapper.getRoleByName(String.valueOf(params.get("roleName")));
        if(list.size()>0){
            logger.error("角色名称已存在");
            throw new Exception("角色名称已存在");
        }
        String parentRoleName = String.valueOf(params.get("parentRoleName"));
        List<ParentRoleVm> parentlist = new ArrayList<>();
        if(StringUtils.isNotBlank(parentRoleName)){
            parentlist = roleMapper.getRoleByName(parentRoleName);
        }
        Role role = new Role();
        Date now = nowDateTime();
        String username = SecurityUtils.getCurrentUserLogin().get();
        TableIdSizeEvt evt = new TableIdSizeEvt(DatabaseConstant.TABLE_NAME_ROLE,DatabaseConstant.ID_SIZE);
        Long roleId = baseQueryClient.getTableId(evt);
        String parentFullRoleId = "," + roleId + ",";

        *//*设置角色参数*//*
        role.setRoleId(roleId);
        if(parentlist.size()>0){
            Long parentId  = parentlist.get(0).getRoleId();
            role.setParentRoleId(parentId);
            parentFullRoleId = parentlist.get(0).getFullRoleId() + parentFullRoleId;
            parentFullRoleId = parentFullRoleId.replace(",,",",");
        }
        role.setRoleFlag(1);
        role.setFullRoleId(parentFullRoleId);
        role.setRoleName(String.valueOf(params.get("roleName")));
        role.setDescription(String.valueOf(params.get("description")));
        role.setInsertTime(now);
        role.setUpdateTime(now);
        role.setCreateUserName(username);
        role.setUpdateUserName(username);

        roleRepository.save(role);*/
    }

    public Date nowDateTime() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowDate = format.format(new Date());
        return format.parse(nowDate);
    }

    @Override
    public void saveRoleWithUser(SaveRoleWithUserVm vm) {
        List<String> delUserId = vm.getDelUserId();
        List<String> addUserId = vm.getAddUserId();
        Long roleId = vm.getRoleId();
        List<String> finalDelId = new ArrayList<String>(delUserId);
        List<String> finalAddId = new ArrayList<String>(addUserId);
        finalDelId.removeAll(addUserId);
        finalAddId.removeAll(delUserId);
        RelationEvt evt = new RelationEvt();
        evt.setId(roleId);
        if (finalDelId.size() > 0) {
            evt.setRelateIds(finalDelId);
            roleMapper.delUsersFromRole(evt);
        }
        if (finalAddId.size() > 0) {
            evt.setRelateIds(finalAddId);
            roleMapper.addUserRole(evt);
        }
    }


    @Override
    public List<ExportRolePermissionVm> getRolePermissionExport(QryRoleEvt evt) {
        //查询角色-权限表
        List<ExportRolePermissionVm> roleNameAndMenuId = roleMapper.getRolePermission();
        System.out.println("====================================================" + roleNameAndMenuId);
        //查询菜单表
        List<MenuIdAndNameVm> allMenu = menuMapper.qryAllMenu();
        //把全量菜单id替换成全量菜单名
        for (int k = 0; k < allMenu.size(); k++) {
            //把每个菜单的全量id进行切割
            String[] fullMenuId = allMenu.get(k).getFullMenuId().split(",");
            String fullMenuName = "";
            //把全量id里的一个个id改成菜单名
            for (int m = 1; m < fullMenuId.length; m++) {
                for (int i = 0; i < allMenu.size(); i++) {
                    if (fullMenuId[m].compareTo(allMenu.get(i).getMenuId()) == 0) {
                        fullMenuName += allMenu.get(i).getMenuNameCn();
                        if (m < fullMenuId.length - 1) {
                            fullMenuName += "/";
                        }
                    }
                }
            }
            allMenu.get(k).setFullMenuName(fullMenuName);
        }

        //角色和菜单整合
        for (int j = 0; j < roleNameAndMenuId.size(); j++) {
            for (MenuIdAndNameVm menu : allMenu) {
                if (roleNameAndMenuId.get(j).getPermission().equals(menu.getMenuId())) {
                    roleNameAndMenuId.get(j).setPermission(menu.getMenuNameCn());
                    roleNameAndMenuId.get(j).setFullPermission(menu.getFullMenuName());
                }

            }
        }
        return roleNameAndMenuId;
    }

    @Override
    public void addUserRoleNew(RelationEvt evt) {
        //先删除原关联数据
        roleMapper.delUserRoleAll(evt.getId());
        //保存新的关联用户
        roleMapper.addUserRole(evt);
    }

    @Override
    public Boolean queryRoleUser(Long id) {
        //判断该角色是否绑定用户
        Boolean bl = true;
        Integer count = roleMapper.queryRoleUser(id);
        if (count > 0) {
            bl = false;
        }
        return bl;
    }

    @Override
    public Boolean queryRoleGroup(Long id) {
        //判断该角色是否绑定用户组
        Boolean bl = true;
        Integer count = roleMapper.queryRoleGroup(id);
        if (count > 0) {
            bl = false;
        }
        return bl;
    }

}
